package com.sleep.psy.external_server.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateUtils {


    private static SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    private static SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
    private static SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMddHHmmss");
    private static SimpleDateFormat sdf4 = new SimpleDateFormat("yyyyMMdd");
    private static SimpleDateFormat sdf5 = new SimpleDateFormat("yyyy-MM-dd");

    private static SimpleDateFormat sdf6 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    public static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    public final static String DATE_MONTH = "MM";

    public final static String DATE_FORMAT = "yyyy-MM-dd";

    public final static String DATE_FORMAT_SIMPLE = "yyyyMMdd";

    public final static String DATE_FORMAT_YYMMDD = "yyMMdd";

    public final static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_TIME_FORMAT_WINTIME = "yyyy-MM-dd HH.mm.ss";

    public final static String DATE_FORMAT_CHINESE = "yyyy年M月d日";

    public final static String DATE_FORMAT_YYYYMMDDHHmmss = "yyyyMMddHHmmss";

    public final static String DATE_FORMAT_YYYYMMDDHHmmssSSS = "yyyyMMddHHmmssSSS";

    public final static String DATE_FORMAT_YYYYMM = "yyyyMM";

    public final static String DATE_FORMAT_YYYY_MM = "yyyy-MM";

    public final static String DATE_FORMAT_DD = "dd";

    public final static String DATE_FORMAT_PATH_YYYYMM = "yyyy/MM";

    public final static String DATE_FORMAT_PATH_YYYYMMDD = "yyyy/MM/dd";

    public static final String DATE_SIMPLE_DATE_FORMAT_TIMESTAMP_INTIM = "yyyy/MM/dd";

    public final static String DATE_FORMAT_YYYY = "yyyy-MM-dd HH:mm:ss";

    public final static String DATE_FORMAT_M_D = "M.d";

    public static long getCurrentTime() {
        long currentTime = new Date().getTime();
        return currentTime;
    }

    public static String formatDate(Date date) {
        return sdf1.format(date);
    }

    public static String formatDate1(Date date) {
        return sdf2.format(date);
    }

    public static String formatDate2(Date date) {
        return sdf3.format(date);
    }

    public static String formatDate4(Date date) {
        return sdf6.format(date);
    }

    public static String formatDate3(Date date) {
        return sdf5.format(date);
    }


    public static String format(long date, String dateFormat) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(date * 1000);
    }

    public static String formatByDate(Date date, String dateFormat) {
        if (date == null) return "";
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        return sdf.format(date);
    }

    /**
     * yyyy年MM月dd日
     *
     * @return
     */
    public static String getDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        return sdf.format(new Date());
    }

    /**
     * Date 转换为字符串
     *
     * @param date
     * @return
     */
    public static String dateToDateStr(Date date) {
        if (date == null) {
            return "";
        }
        return new SimpleDateFormat(TIME_PATTERN).format(date);
    }

    /**
     * long 转换为时间格式的字符串
     *
     * @param date
     * @return
     */
    public static String longToDateStr(long date) {
        return new SimpleDateFormat(TIME_PATTERN).format(new Date(date * 1000));

    }

    /**
     * 获取昨天的日期
     *
     * @return
     */
    public static String getYesterday() {
        Date today = new Date();
        Date yesterday = new Date(today.getTime() - 86400000L);
        return sdf4.format(yesterday);
    }

    /**
     * 获取今天的日期
     *
     * @return
     */
    public static String getToday() {
        Date today = new Date();

        return sdf5.format(today);
    }

    public static Long getCurrentTimeSeconds() {
        return System.currentTimeMillis() / 1000;
    }

    public static Long getCurrentTimeMillis() {
        return System.currentTimeMillis();
    }

    public static String getNextYear(){
        Calendar curr = Calendar.getInstance();
        curr.set(Calendar.YEAR,curr.get(Calendar.YEAR)+1);
        Date date=curr.getTime();
        return sdf5.format(date);
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param date1 小日期
     * @param date2 大日期
     * @return 返回秒
     */
    public static int differentDaysByMillisecond (String date1,String date2){
        try {
            Date date11 = sdf5.parse(date1);
            Date date22 = sdf5.parse(date2);
            int days = (int) ((date22.getTime() - date11.getTime()) / 1000*24*60);
            return days;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static int differentDaysByMillisecond1 (String date1,String date2){
        try {
            Date date11 = sdf6.parse(date1);
            Date date22 = sdf6.parse(date2);
            int days = (int) ((date22.getTime() - date11.getTime()) / 1000);
            return days;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 将时区格式的日期转换为date类型
     * @author wenliguo
     * @date 2025/5/12 11:26
     * @param timezone 时区格式的日期
     * @return java.util.Date
     */
    public static Date getGMTDateTime(String timezone) {
        TimeZone tz = TimeZone.getTimeZone(timezone); //GMT+8:00
        Date date = Calendar.getInstance().getTime();
        try {

            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            formatter.setTimeZone(tz);
            String str = formatter.format(date);
            formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            date = formatter.parse(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }


    /**
     * 获取时间戳精确到天
     * @author wenliguo
     * @date 2025/5/28 13:36
     * @param date 日期
     * @return java.lang.String
     */
    public static String getDatestamp(Date date) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT_SIMPLE);
        if(date == null) {
            date = new Date();
        }
        datestr = df.format(date);
        return datestr;
    }

    /**
     * 当前年
     * @author wenliguo
     * @date 2025/5/28 13:36
     * @return int
     */
    public static int getYear(){
        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));    //获取东八区时间;
        return c.get(Calendar.YEAR);
    }

    /**
     *  获取月份，0表示1月份
     * @author wenliguo
     * @date 2025/5/28 13:36
     * @return int
     */
    public static int getMonth(){
        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));    //获取东八区时间;
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前天数
     * @author wenliguo
     * @date 2025/5/28 13:37
     * @return int
     */
    public static int getDay(){
        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));    //获取东八区时间;
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取当前月份 01 02格式
     * @author wenliguo
     * @date 2025/5/28 13:37
     * @return java.lang.String
     */
    public static String getMonth2() {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_MONTH);
        datestr = df.format(new Date());
        return datestr;
    }
    /**

     /**
     * @author wenliguo
     * @date 获取当前日期 13:37
     * @return java.lang.String
     */
    public static String getCurrentDate() {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT);
        datestr = df.format(new Date());
        return datestr;
    }

    /**
     * 获取当前日期
     * @author wenliguo
     * @date 2025/5/28 13:37
     * @return java.lang.String
     */
    public static String getCurrentDateSimple() {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT_SIMPLE);
        datestr = df.format(new Date());
        return datestr;
    }

    /**
     * 获取当前日期时间
     * @author wenliguo
     * @date 2025/5/28 13:37
     * @return java.lang.String
     */
    public static String getCurrentDateTime() {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
        datestr = df.format(new Date());
        return datestr;
    }

    /**
     * 获取当前时间戳
     * @author wenliguo
     * @date 2025/5/28 13:38
     * @return java.lang.String
     */
    public static String getTimestamp() {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT_YYYYMMDDHHmmss);
        datestr = df.format(new Date());
        return datestr;
    }

    /**
     * 获取当前时间戳
     * @author wenliguo
     * @date 2025/5/28 13:38
     * @return java.lang.String
     */
    public static String getLongTimestamp() {
        return String.valueOf(System.currentTimeMillis()/1000);
    }

    /**
     * 获取当前日期时间
     * @author wenliguo
     * @date 2025/5/28 13:38
     * @param Dateformat 日期格式
     * @return java.lang.String
     */
    public static String getCurrentDateTime(String Dateformat) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(Dateformat);
        datestr = df.format(new Date());
        return datestr;
    }

    public static String dateToDateTime(Date date) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
        datestr = df.format(date);
        return datestr;
    }

    public static String dateToDateTimeByFormat(Date date,String format) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(format);
        datestr = df.format(date);
        return datestr;
    }

    /**
     * 将字符串日期转换为日期格式（精确到天）
     * @author wenliguo
     * @date 2025/5/28 13:38
     * @param datestr 日期
     * @return java.util.Date
     */
    public static Date stringToDate(String datestr) {

        if (datestr == null || datestr.equals("")) {
            return null;
        }
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT);
        try {
            date = df.parse(datestr);
        } catch (ParseException e) {
            date = DateUtils.stringToDate(datestr, "yyyyMMdd");
        }
        return date;
    }

    /**
     * 字符串时间转日期格式（精确到秒）
     * @author wenliguo
     * @date 2025/5/28 13:40
     * @param datestr 日期
     * @return java.util.Date
     */
    public static Date stringToDatetime(String datestr) {

        if (datestr == null || datestr.equals("")) {
            return null;
        }
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
        try {
            date = df.parse(datestr);
        } catch (ParseException e) {
            date = DateUtils.stringToDate(datestr, "yyyy-MM-dd HH:mm:ss");
        }
        return date;
    }

    /**
     * 将字符串日期转换为日期格式 自定义格式
     * @author wenliguo
     * @date 2025/5/28 13:41
     * @param datestr 日期
     * @param dateformat 格式
     * @return java.util.Date
     */
    public static Date stringToDate(String datestr, String dateformat) {
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat(dateformat);
        try {
            date = df.parse(datestr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 将日期格式日期转换为字符串格式
     * @author wenliguo
     * @date 2025/5/28 13:41
     * @param date 日期
     * @return java.lang.String
     */
    public static String dateToString(Date date) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT);
        datestr = df.format(date);
        return datestr;
    }

    /**
     * 将日期格式日期转换为字符串格式
     * @author wenliguo
     * @date 2025/5/28 13:41
     * @param date 日期
     * @return java.lang.String
     */
    public static String dateToDayString(Date date) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT_SIMPLE);
        datestr = df.format(date);
        return datestr;
    }

    /**
     * 将日期格式日期转换为字符串格式
     * @author wenliguo
     * @date 2025/5/28 13:41
     * @param date 日期
     * @return java.lang.String
     */
    public static String dateToDayChineseString(Date date) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.DATE_FORMAT_CHINESE);
        datestr = df.format(date);
        return datestr;
    }


    /**
     * 将日期格式日期转换为字符串格式 自定義格式
     * @author wenliguo
     * @date 2025/5/28 13:41
     * @param date 日期
     * @param dateformat 格式
     * @return java.lang.String
     */
    public static String dateToString(Date date, String dateformat) {
        String datestr = null;
        SimpleDateFormat df = new SimpleDateFormat(dateformat);
        datestr = df.format(date);
        return datestr;
    }

    /**
     * 获取日期的DAY值
     * @author wenliguo
     * @date 2025/5/28 13:41
     * @param date 输入日期
     * @return int
     */
    public static int getDayOfDate(Date date) {
        int d = 0;
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        d = cd.get(Calendar.DAY_OF_MONTH);
        return d;
    }

    /**
     * 获取日期的MONTH值
     * @author wenliguo
     * @date 2025/5/28 13:41
     * @param date 输入日期
     * @return int
     */
    public static int getMonthOfDate(Date date) {
        int m = 0;
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        m = cd.get(Calendar.MONTH) + 1;
        return m;
    }

    /**
     * 获取日期的YEAR值
     * @author wenliguo
     * @date 2025/5/28 13:42
     * @param date 日期
     * @return int
     */
    public static int getYearOfDate(Date date) {
        int y = 0;
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        y = cd.get(Calendar.YEAR);
        return y;
    }

    /**
     * 获取星期几
     * @author wenliguo
     * @date 2025/5/28 13:42
     * @param date 日期
     * @return int
     */
    public static int getWeekOfDate(Date date) {
        int wd = 0;
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        wd = cd.get(Calendar.DAY_OF_WEEK) - 1;
        return wd;
    }

    /**
     * 获取输入日期的当月第一天
     * @author wenliguo
     * @date 2025/5/28 13:42
     * @param date 日期
     * @return java.util.Date
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.set(Calendar.DAY_OF_MONTH, 1);
        return cd.getTime();
    }

    /**
     * 获取输入日期的当月的指定的某一天
     * @author wenliguo
     * @date 2025/5/28 13:42
     * @param date 日期
     * @param day 天数
     * @return java.util.Date
     */
    public static Date getSpecifiedDayOfMonth(Date date,int day) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.set(Calendar.DAY_OF_MONTH, day);
        return cd.getTime();
    }

    /**
     * 获得输入日期的当月最后一天
     * @author wenliguo
     * @date 2025/5/28 13:43
     * @param date 日期
     * @return java.util.Date
     */
    public static Date getLastDayOfMonth(Date date) {
        return DateUtils.addDay(DateUtils.getFirstDayOfMonth(DateUtils.addMonth(date, 1)), -1);
    }

    /**
     * 获得输入日期的当月倒数第二天
     * @author wenliguo
     * @date 2025/5/28 13:43
     * @param date 日期
     * @return java.util.Date
     */
    public static Date getLastSecondDayOfMonth(Date date) {
        return DateUtils.addDay(DateUtils.getFirstDayOfMonth(DateUtils.addMonth(date, 1)), -2);
    }

    /**
     * 判断是否是闰年
     * @author wenliguo
     * @date 2025/5/28 13:43
     * @param date 日期
     * @return boolean
     */
    public static boolean isLeapYEAR(Date date) {

        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        int year = cd.get(Calendar.YEAR);

        if (year % 4 == 0 && year % 100 != 0 | year % 400 == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据整型数表示的年月日，生成日期类型格式
     * @author wenliguo
     * @date 2025/5/28 13:44
     * @param year 年
     * @param month 月
     * @param day 日
     * @return java.util.Date
     */
    public static Date getDateByYMD(int year, int month, int day) {
        Calendar cd = Calendar.getInstance();
        cd.set(year, month - 1, day);
        return cd.getTime();
    }

    /**
     * 获取年周期
     * @author wenliguo
     * @date 2025/5/28 13:44
     * @param date 对应日输入日期
     * @param iyear 年数
     * @return java.util.Date
     */
    public static Date getYearCycleOfDate(Date date, int iyear) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);

        cd.add(Calendar.YEAR, iyear);

        return cd.getTime();
    }

    /**
     * 获取月周期对应日
     * @author wenliguo
     * @date 2025/5/28 13:44
     * @param date 日期
     * @param i 数字
     * @return java.util.Date
     */
    public static Date getMonthCycleOfDate(Date date, int i) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);

        cd.add(Calendar.MONTH, i);

        return cd.getTime();
    }

    /**
     * 计算 fromDate 到 toDate 相差多少年
     * @author wenliguo
     * @date 2025/5/28 13:45
     * @param fromDate 开始
     * @param toDate 结束
     * @return int
     */
    public static int getYearByMinusDate(Date fromDate, Date toDate) {
        Calendar df = Calendar.getInstance();
        df.setTime(fromDate);

        Calendar dt = Calendar.getInstance();
        dt.setTime(toDate);

        return dt.get(Calendar.YEAR) - df.get(Calendar.YEAR);
    }

    /**
     * 计算 fromDate 到 toDate 相差多少个月
     * @author wenliguo
     * @date 2025/5/28 13:45
     * @param fromDate 开始
     * @param toDate 结束
     * @return int
     */
    public static int getMonthByMinusDate(Date fromDate, Date toDate) {
        Calendar df = Calendar.getInstance();
        df.setTime(fromDate);

        Calendar dt = Calendar.getInstance();
        dt.setTime(toDate);

        return dt.get(Calendar.YEAR) * 12 + dt.get(Calendar.MONTH)
                - (df.get(Calendar.YEAR) * 12 + df.get(Calendar.MONTH));
    }

    /**
     * 计算 fromDate 到 toDate 相差多少天
     * @author wenliguo
     * @date 2025/5/28 13:45
     * @param fromDate 开始
     * @param toDate 结束
     * @return long
     */
    public static long getDayByMinusDate(Object fromDate, Object toDate) {

        Date f = DateUtils.chgObject(fromDate);

        Date t = DateUtils.chgObject(toDate);

        long fd = f.getTime();
        long td = t.getTime();

        return (td - fd) / (24L * 60L * 60L * 1000L);
    }

    /**
     * 计算 fromDate 到 toDate 相差多少天 如  1小时内为刚刚，1天内为n小时前；10天内为N天前，
     * @author wenliguo
     * @date 2025/5/28 13:46
     * @param begin 开始
     * @param end 结束
     * @return java.lang.String
     */
    public static String getDateDescByTwoDate(Date begin, Date end) {


        long bd = begin.getTime();
        long ed = end.getTime();
        long s = (ed - bd) / (1000L * 60L); //计算差距时间为分钟
        if(s  < 60) {
            return "刚刚";
        }
        String dateString = "";
        s = s / (60L); //小时
        if(s  < 24) {
            return  dateString.concat(String.valueOf(s)).concat("小时前");
        }
        s = s / (24L); //天数
        if(s < 10) {
            return  dateString.concat(String.valueOf(s)).concat("天前");
        }
        return dateToDateTime(begin);
    }

    /**
     * 计算年龄
     * @author wenliguo
     * @date 2025/5/28 13:46
     * @param birthday 生日日期
     * @param calcDate 要计算的日期点
     * @return int
     */
    public static int calcAge(Date birthday, Date calcDate) {

        int cYear = DateUtils.getYearOfDate(calcDate);
        int cMonth = DateUtils.getMonthOfDate(calcDate);
        int cDay = DateUtils.getDayOfDate(calcDate);
        int bYear = DateUtils.getYearOfDate(birthday);
        int bMonth = DateUtils.getMonthOfDate(birthday);
        int bDay = DateUtils.getDayOfDate(birthday);

        if (cMonth > bMonth || (cMonth == bMonth && cDay > bDay)) {
            return cYear - bYear;
        } else {
            return cYear - 1 - bYear;
        }
    }

    /**
     * 以指定日期，计算相差月份
     * @author wenliguo
     * @date 2025/5/28 13:47
     * @param startDay 日期1
     * @param endDay 日期2
     * @param day  指定日期
     * @return int
     */
    public static int calcMonthsByDay(Date startDay, Date endDay, int day) {
        int res = 0;
        int cYear = DateUtils.getYearOfDate(startDay);
        int cMonth = DateUtils.getMonthOfDate(startDay);
        int cDay = DateUtils.getDayOfDate(startDay);
        int bYear = DateUtils.getYearOfDate(endDay);
        int bMonth = DateUtils.getMonthOfDate(endDay);
        int bDay = DateUtils.getDayOfDate(endDay);
        if(cYear != bYear){
            res = (cYear - bYear) * 12;
        }
        if(cDay > day) {
            cMonth += 1;
        }
        if(bDay > day) {
            bMonth += 1;
        }
        res  += cMonth - bMonth;
        return res;
    }

    /**
     * 从身份证中获取出生日期
     * @author wenliguo
     * @date 2025/5/28 13:47
     * @param idno 身份证号码
     * @return java.lang.String
     */
    public static String getBirthDayFromIDCard(String idno) {
        Calendar cd = Calendar.getInstance();
        if (idno.length() == 15) {
            cd.set(Calendar.YEAR, Integer.parseInt("19" + idno.substring(6, 8)));
            cd.set(Calendar.MONTH, Integer.parseInt(idno.substring(8, 10)) - 1);
            cd.set(Calendar.DAY_OF_MONTH, Integer.parseInt(idno.substring(10, 12)));
        } else if (idno.length() == 18) {
            cd.set(Calendar.YEAR, Integer.parseInt(idno.substring(6, 10)));
            cd.set(Calendar.MONTH, Integer.parseInt(idno.substring(10, 12)) - 1);
            cd.set(Calendar.DAY_OF_MONTH, Integer.parseInt(idno.substring(12, 14)));
        }
        return DateUtils.dateToString(cd.getTime());
    }

    /**
     * 增加秒 时间 秒数
     * @author wenliguo
     * @date 2025/5/28 13:47
     * @param date 日期
     * @param iSec 在输入时间上增加（+）或减去（-）分钟数
     * @return java.util.Date
     */
    public static Date addSeconds(Date date, int iSec) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.SECOND, iSec);
        return cd.getTime();
    }

    /**
     * 在输入时间上增加（+）或减去（-）分钟数
     * @author wenliguo
     * @date 2025/5/28 13:48
     * @param date 输入日期
     * @param iMin 要增加或减少的天数
     * @return java.util.Date
     */
    public static Date addMinutes(Date date, int iMin) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.add(Calendar.MINUTE, iMin);
        return cd.getTime();
    }


    /**
     * 在输入日期上增加（+）或减去（-）天数
     * @author wenliguo
     * @date 2025/5/28 13:49
     * @param date 输入日期
     * @param iday 要增加或减少的天数
     * @return java.util.Date
     */
    public static Date addDay(Date date, int iday) {
        Calendar cd = Calendar.getInstance();

        cd.setTime(date);

        cd.add(Calendar.DAY_OF_MONTH, iday);

        return cd.getTime();
    }

    /**
     * 在输入日期上增加（+）或减去（-）月份
     * @author wenliguo
     * @date 2025/5/28 13:49
     * @param date 输入日期
     * @param imonth 要增加或减少的月分数
     * @return java.util.Date
     */
    public static Date addMonth(Date date, int imonth) {
        Calendar cd = Calendar.getInstance();

        cd.setTime(date);

        cd.add(Calendar.MONTH, imonth);

        return cd.getTime();
    }

    /**
     * 在输入日期上增加（+）或减去（-）年份
     * @author wenliguo
     * @date 2025/5/28 13:49
     * @param date 输入日期
     * @param iyear 要增加或减少的年数
     * @return java.util.Date
     */
    public static Date addYear(Date date, int iyear) {
        Calendar cd = Calendar.getInstance();

        cd.setTime(date);

        cd.add(Calendar.YEAR, iyear);

        return cd.getTime();
    }

    /**
     * 将object 时间转为 date类型
     * @author wenliguo
     * @date 2025/5/28 13:50
     * @param date 日期
     * @return java.util.Date
     */
    public static Date chgObject(Object date) {

        if (date != null && date instanceof Date) {
            return (Date) date;
        }

        if (date != null && date instanceof String) {
            return DateUtils.stringToDate((String) date);
        }

        return null;

    }

    public static long getAgeByBirthday(String date) {

        Date birthday = stringToDate(date, DATE_FORMAT);
        long sec = System.currentTimeMillis() - birthday.getTime();

        long age = sec / (1000 * 60 * 60 * 24) / 365;

        return age;
    }


    public static String getCurrentTimeMills() {
        long mills = System.currentTimeMillis();
        return mills+"";
    }

    public static String getUnixTime() {
        long mills = System.currentTimeMillis()/1000;
        return mills+"";
    }

    public static Long getUnixTimeL() {
        return System.currentTimeMillis()/1000;
    }


    //判断选择的日期是否是本周
    public static boolean isThisWeek(long time)
    {
        Calendar calendar = Calendar.getInstance();
        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        calendar.setTime(new Date(time));
        int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        if(paramWeek==currentWeek){
            return true;
        }
        return false;
    }
    //判断选择的日期是否是今天
    public static boolean isToday(long time)
    {
        return isThisTime(time, DATE_FORMAT);
    }
    //判断选择的日期是否是本月
    public static boolean isThisMonth(long time)
    {
        return isThisTime(time,"yyyy-MM");
    }
    private static boolean isThisTime(long time,String pattern) {
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        String param = sdf.format(date);//参数时间
        String now = sdf.format(new Date());//当前时间
        if(param.equals(now)){
            return true;
        }
        return false;
    }
    public static Date todayLastDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }
    public static Date todayFirstDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 将Java指定格式日期转换成Unix时间戳
     * @author wenliguo
     * @date 2025/5/28 13:50
     * @param dateStr 日期
     * @param format 格式
     * @return java.lang.String
     */
    public static String Date2TimeStamp(String dateStr, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return String.valueOf(sdf.parse(dateStr).getTime() / 1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 取得当前时间戳（精确到秒）
     * @author wenliguo
     * @date 2025/5/28 13:51
     * @return java.lang.String
     */
    public static String getNowTimeStamp() {
        long time = System.currentTimeMillis();
        String nowTimeStamp = String.valueOf(time / 1000);
        return nowTimeStamp;
    }

    /**
     * getPlanDate: 获取几个月之后的那一天
     * @param nperNo 期数，第几期
     * @return Date
     * @throws ParseException
     */
    public static Date getPlanDate(Integer startDay, Integer nperNo) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, startDay);
        calendar.add(Calendar.MONTH, nperNo);
        return calendar.getTime();
    }

    /**
     *  获取几个月之后的那一天
     * @param nperNo
     * @return
     * @date 2019年3月22日下午7:44:59
     */
    public static Date getPlanDateFixedDay(Integer startDay, Integer nperNo) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, startDay);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.add(Calendar.MONTH, nperNo);
        return calendar.getTime();
    }

    /**
     * 获取几个月之后的那一天
     * @param startDay 固定天数
     * @param nperNo 月数，第几个月
     * @param calculationDate 时间起始点
     * @return
     * @date: 2019-09-18 18:41:12
     */
    public static Date getPlanDateFixedDayByDate(Integer startDay, Integer nperNo, Date calculationDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(calculationDate);
        calendar.set(Calendar.DAY_OF_MONTH, startDay);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.add(Calendar.MONTH, nperNo);
        return calendar.getTime();
    }

    /**
     * @Description: 获取几个月之后的那一天的最后时分秒
     * @param startDay 固定天数
     * @param nperNo 月数，第几个月
     * @param calculationDate 时间起始点
     * @return
     * @date: 2020-07-28 11:14:20
     */
    public static Date getPlanDateFixedDayHmsByDate(Integer startDay, Integer nperNo, Date calculationDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(calculationDate);
        calendar.set(Calendar.DAY_OF_MONTH, startDay);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.add(Calendar.MONTH, nperNo);
        return calendar.getTime();
    }

    /**
     *  获取几个月之后的那一天（该方法为扩展方法，0为从后开始第一天，-1为从月底开始第二天）
     * @param startDay 固定天数
     * @param nperNo 月数，第几个月
     * @param calculationDate 时间起始点
     * @return
     * @date: 2019-09-18 18:41:12
     */
    public static Date getPlanDateFixedDayByDateExpansion(Integer startDay, Integer nperNo, Date calculationDate) {
        if(startDay > 0) {
            Date date = getPlanDateFixedDayByDate(startDay, nperNo, calculationDate);
            return date;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(calculationDate);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.add(Calendar.MONTH, nperNo+1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        //设置时间为 负数
        int i = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, i+startDay);
        return calendar.getTime();
    }

    /**
     *  获取36期计划开始时间
     * @param nperNo 月数，第几个月
     * @param calculationDate 时间起始点
     * @return
     * @date: 2019-09-18 18:41:12
     */
    public static Date getCmpayPlanTimeThirtySix(Integer nperNo, Date calculationDate) {
        nperNo = nperNo - 1;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(calculationDate);
        calendar.add(Calendar.MONTH, nperNo);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     *  获取36期计划结束时间
     * @param nperNo 月数，第几个月
     * @param calculationDate 时间起始点
     * @return
     * @date: 2019-09-18 18:41:12
     */
    public static Date getCmpayFinalTimeThirtySix(Integer nperNo, Date calculationDate) {
        nperNo = nperNo - 1;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(calculationDate);
        calendar.add(Calendar.MONTH, nperNo);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     *  获取几个月之后的那一天（跟上面的方法唯一的区别就是，这个方法不置空时分秒）
     * @param startDay 固定天数
     * @param nperNo 月份
     * @return
     * @date 2019年8月1日上午11:01:35
     */
    public static Date getPlanDateDay(Integer startDay, Integer nperNo) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, startDay);
        calendar.add(Calendar.MONTH, nperNo);
        return calendar.getTime();
    }

    /**
     *  获取几个月之后的当天（跟上面的方法唯一的区别就是，这个方法不置空时分秒）
     * @return
     * @date 2019年8月1日上午11:01:35
     */
    public static Date getPlanCurrentDay(Integer dayNo) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
//		calendar.add(Calendar.MONTH, dayNo);
        calendar.add(Calendar.DATE, dayNo);
        return calendar.getTime();
    }

    /**
     *  判断是否同一天
     * @param date1
     * @param date2
     * @return
     * @date: 2019-08-14 16:15:33
     */
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return isSameDay(cal1, cal2);
    }

    /**
     * 判断是否同一天
     * @param cal1
     * @param cal2
     * @return
     * @date: 2019-08-14 16:15:43
     */
    public static boolean isSameDay(Calendar cal1, Calendar cal2) {
        if (cal1 == null || cal2 == null) {
            return false;
        }
        return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
    }

    /**
     * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
     */
    public static String formatDate(Date date, Object... pattern) {
        SimpleDateFormat simpleDateFormat = null;
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            simpleDateFormat = new SimpleDateFormat(pattern[0].toString());
            formatDate = simpleDateFormat.format(date);
        } else {
            simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
            formatDate = simpleDateFormat.format(date);
        }
        return formatDate;
    }

    /**
     * getPlanDate: 获取当天
     * @return Date
     * @throws ParseException
     */
    public static Date getCurrentDay() throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);//时
        calendar.set(Calendar.MINUTE, 0);//分
        calendar.set(Calendar.SECOND, 0);//秒
        calendar.set(Calendar.MILLISECOND, 0);//毫秒
        return calendar.getTime();
    }

    /**
     * getPlanDate: 获取几个月之后的那一天
     * @param nperNo 期数，第几期
     * @return Date
     * @throws ParseException
     */
    public static Date getPlanDate(Date startDate, Integer nperNo) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(Calendar.MONTH, nperNo);
        calendar.set(Calendar.HOUR_OF_DAY, 0);//时
        calendar.set(Calendar.MINUTE, 0);//分
        calendar.set(Calendar.SECOND, 0);//秒
        calendar.set(Calendar.MILLISECOND, 0);//毫秒
        return calendar.getTime();
    }

    /**
     * getPlanDate: 获取几个月之后的那一天
     * @param startDate 开始时间
     * @param dayNo 期数，第几期
     * @return Date
     * @throws ParseException
     */
    public static Date getDateAddDay(Date startDate, Integer dayNo) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        calendar.add(Calendar.DAY_OF_MONTH, dayNo);
        calendar.set(Calendar.HOUR_OF_DAY, 0);//时
        calendar.set(Calendar.MINUTE, 0);//分
        calendar.set(Calendar.SECOND, 0);//秒
        calendar.set(Calendar.MILLISECOND, 0);//毫秒
        return calendar.getTime();
    }

    /**
     * 判断时间是否处于某个时间段内
     * @param time 需要比较的时间
     * @param from 起始时间
     * @param to 结束时间
     * @return
     */
    public static boolean belongCalendar(Date time, Date from, Date to) {
        Calendar date = Calendar.getInstance();
        date.setTime(time);
        Calendar after = Calendar.getInstance();
        after.setTime(from);
        Calendar before = Calendar.getInstance();
        before.setTime(to);
        if (date.after(after) && date.before(before)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @Description: 获取中文完整时间
     * @return
     * @date: 2020-09-03 13:50:47
     */
    public static String getDateStr() {
        String date = "";
        date = new SimpleDateFormat("yyyy").format(new Date()) + "年"
                + new SimpleDateFormat("MM").format(new Date()) + "月"
                + new SimpleDateFormat("dd").format(new Date()) + "日"
                + new SimpleDateFormat("HH").format(new Date()) + "时"
                + new SimpleDateFormat("mm").format(new Date()) + "分"
                + new SimpleDateFormat("ss").format(new Date()) + "秒";
        return date ;
    }

    /**
     * 获得某天最大时间 2020-02-19 23:59:59
     * @param date
     * @return
     * @Description
     * @date 2020-12-17 14:06:35
     */
    public static Date getEndOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());;
        LocalDateTime endOfDay = localDateTime.with(LocalTime.MAX);
        return Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获得某天最小时间 2020-02-17 00:00:00
     * @param date
     * @return
     * @Description
     * @date 2020-12-17 14:06:35
     */
    public static Date getStartOfDay(Date date) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault());
        LocalDateTime startOfDay = localDateTime.with(LocalTime.MIN);
        return Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * @Description: 日期转换，将20180524转为2018-05-24 10:37:26，时分秒为当前时间
     * @param str
     * @return
     * @date: 2021-01-11 10:30:11
     */
    public static Date compactStrToDateTime(String str) {
        Date date = new Date();
        Date finalTime = new Date();
        try {
            if(!StringUtils.isEmpty(str)) {
                date = new SimpleDateFormat(DATE_FORMAT_SIMPLE).parse(str);
            }
            Calendar cal = Calendar.getInstance();
            int hour = cal.get(Calendar.HOUR_OF_DAY);
            int minute = cal.get(Calendar.MINUTE);
            int secound = cal.get(Calendar.SECOND);

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, hour);//时
            calendar.set(Calendar.MINUTE, minute);//分
            calendar.set(Calendar.SECOND, secound);//秒

            finalTime = calendar.getTime();
        } catch (ParseException e) {
        }
        return finalTime;
    }

    /**
     * @param date
     * @return
     * @date 2020-09-01 10:37:43
     * @Description 获取时间戳  精确到天
     */
    public final static String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";

    /**
     *  获取两个日期相差的月数
     * @param d1    较大的日期
     * @param d2    较小的日期
     * @return  如果d1>d2返回 月数差 否则返回0
     */
    public static int getMonthDiff(Date d1, Date d2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(d1);
        c2.setTime(d2);
        //if(c1.getTimeInMillis() < c2.getTimeInMillis()) return 0;
        int year1 = c1.get(Calendar.YEAR);
        int year2 = c2.get(Calendar.YEAR);
        int month1 = c1.get(Calendar.MONTH);
        int month2 = c2.get(Calendar.MONTH);
        int day1 = c1.get(Calendar.DAY_OF_MONTH);
        int day2 = c2.get(Calendar.DAY_OF_MONTH);
        // 获取年的差值 假设 d1 = 2015-8-16  d2 = 2011-9-30
        int yearInterval = year1 - year2;
        // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
        if(month1 < month2 || month1 == month2 && day1 < day2) {
            yearInterval--;
        }
        // 获取月数差值
        int monthInterval =  (month1 + 12) - month2  ;
        if(day1 < day2) {
            monthInterval--;
        }
        monthInterval %= 12;
        return yearInterval * 12 + monthInterval;
    }

}
